class ConcurrencyRun {
    doing = 0;
    done = 0;
    queue = [];
    max = 2;

    constructor(max) {
        if (max) {
            this.max = max;
        }
    }

    async run(task) {
        if (this.doing >= this.max) {
            await new Promise((resolve) => this.queue.push(resolve));
        }

        this.doing++;
        let result = null;

        try {
            result = await task();
        } catch (error) {}

        this.doing--;
        this.done++;

        if (this.queue.length) {
            const resolve = this.queue.shift();
            resolve();
        }

        return result;
    }
}

const task1 = () => new Promise((resolve) => setTimeout(() => resolve(1), 200));
const task2 = () => new Promise((resolve) => setTimeout(() => resolve(2), 500));
const task3 = () => new Promise((resolve) => setTimeout(() => resolve(3), 100));
const task4 = () => new Promise((resolve) => setTimeout(() => resolve(4), 400));
const task5 = () => new Promise((resolve) => setTimeout(() => resolve(5), 300));
const task6 = () => new Promise((resolve) => setTimeout(() => resolve(6), 50));

const queue = [task1, task2, task3, task4, task5, task6];

const concurrencyRun = new ConcurrencyRun(2);

queue.forEach((task) => concurrencyRun.run(task).then((result) => console.log(result)));

// 希望最终输出
// 0，1 2 入
// 200，1 出 3 入
// 300，3 出 4 入
// 500，2 出 5 入
// 700，4 出 6 入
// 750，6 出
// 800，5 出
